using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Reflection;

using Softelvdm.SftTreeNET;

namespace EventViewer {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            sftTreeList.ItemCollection.Clear();

            sftTree1.Columns.MakeOptimal(0, false);
            sftTree1.RowHeaders.MakeOptimal(0, false);
            sftTree1.Splitter.MakeOptimal();
            sftTree1.RecalcHorizontalExtent();
        }

        private string strLastEvent = "";
        private bool fLastEventDup = false;

        // This is a small helper routine to show all properties and fields of an object
        private void DumpValues(string title, object o) {

            string s = "";

            if (strLastEvent == title) {
                if (!fLastEventDup) {
                    s = "Additional " + title + " events ... now suppressed";
                    fLastEventDup = true;
                } else
                    return;
            } else {
                strLastEvent = title;
                fLastEventDup = false;

                PropertyInfo[] api = o.GetType().GetProperties();
                foreach (PropertyInfo pi in api)
                    s += pi.Name + "=" + pi.GetValue(o, new object[] { }) + " ";
                FieldInfo[] afi = o.GetType().GetFields();
                foreach (FieldInfo fi in afi)
                    s += fi.Name + "=" + fi.GetValue(o) + " ";
            }

            ItemClass item = sftTreeList.ItemCollection.Add(new string[] { title, s });
            item.Selected = true;

            sftTreeList.Columns.MakeOptimal(50, true);
            sftTreeList.RecalcHorizontalExtent();
        }

        private void sftTree1_CheckBoxClicked(object sender, Softelvdm.SftTreeNET.PartEventArgs e) {
            DumpValues("CheckBoxClicked", e);
        }

        private void sftTree1_ColumnReordered(object sender, Softelvdm.SftTreeNET.ColumnReorderedEventArgs e) {
            DumpValues("ColumnReordered", e);
        }

        private void sftTree1_ColumnResized(object sender, Softelvdm.SftTreeNET.ColumnResizedEventArgs e) {
            DumpValues("ColumnResized", e);
        }

        private void sftTree1_DragDetected(object sender, Softelvdm.SftTreeNET.DragDetectedEventArgs e) {
            DumpValues("DragDetected", e);

            if (e.Item.UsageLocation != UsageLocationEnum.items)
                return; // ignore header/footer dragging

            e.Handled = true;
            sftTree1.DoDragDrop("In this example, we are dragging a simple text string", DragDropEffects.Copy);
        }

        private void sftTree1_DragDrop(object sender, DragEventArgs e) {
            DumpValues("DragDrop", e);
        }

        private void sftTree1_DragEnter(object sender, DragEventArgs e) {
            DumpValues("DragEnter", e);

            e.Effect = DragDropEffects.Copy; // accept anything
        }

        private void sftTree1_DragLeave(object sender, EventArgs e) {
            DumpValues("DragLeave", e);
        }

        private void sftTree1_DragOver(object sender, DragEventArgs e) {
            DumpValues("DragOver", e);

            e.Effect = DragDropEffects.Copy; // accept anything
        }

        private void sftTree1_EditAllowed(object sender, Softelvdm.SftTreeNET.EditAllowedEventArgs e) {
            DumpValues("EditAllowed", e);

            e.Allowed = (e.Cell.ColumnIndex == 2); // only edit cells in column 2
        }

        private void sftTree1_EditClickOutside(object sender, Softelvdm.SftTreeNET.EditClickOutsideEventArgs e) {
            DumpValues("EditClickOutside", e);
        }

        private void sftTree1_EditEnded(object sender, Softelvdm.SftTreeNET.EditEndedEventArgs e) {
            DumpValues("EditEnded", e);

            // save the new cell text if necessary
            if (e.SaveValue)
                e.Cell.Text = textBox1.Text;

            // hide the text box and make the form the control's parent
            textBox1.Visible = false;
            textBox1.Enabled = false;
            textBox1.Parent = sftTree1.Parent;
        }

        private void sftTree1_EditSetup(object sender, Softelvdm.SftTreeNET.EditSetupEventArgs e) {
            DumpValues("EditSetup", e);

            textBox1.Parent = sftTree1;     // make the tree control the parent window

            textBox1.Text = e.Cell.Text;
            int h = textBox1.Height;

            Rectangle r = e.rCell;
            // limit the control to the right pane - all cell editing takes place in right pane
            r.Intersect(sftTree1.Splitter.Right.ItemsArea);
            int vOffs = (r.Size.Height - textBox1.Height) / 2;
            textBox1.Location = new Point(r.Location.X, r.Location.Y + vOffs);
            textBox1.Width = r.Width;

            // make it visible and enable it
            textBox1.Enabled = true;
            textBox1.Visible = true;

            // off we go!
            textBox1.BringToFront();
            textBox1.Focus();
            e.EditControl = textBox1;
        }

        private void sftTree1_EditValidate(object sender, Softelvdm.SftTreeNET.EditValidateEventArgs e) {
            DumpValues("EditValidate", e);
        }

        private void sftTree1_Enter(object sender, EventArgs e) {
            DumpValues("Enter", e);
        }

        private void sftTree1_FocusObjectChanged(object sender, EventArgs e) {
            DumpValues("FocusObjectChanged", e);
        }

        private void sftTree1_FooterClicked(object sender, Softelvdm.SftTreeNET.FooterClickedEventArgs e) {
            DumpValues("FooterClicked", e);
        }

        private void sftTree1_FooterDoubleClicked(object sender, Softelvdm.SftTreeNET.FooterClickedEventArgs e) {
            DumpValues("FooterDoubleClicked", e);
        }

        private void sftTree1_FooterHeightChanged(object sender, EventArgs e) {
            DumpValues("FooterHeightChanged", e);
        }

        private void sftTree1_GiveFeedback(object sender, GiveFeedbackEventArgs e) {
            DumpValues("GiveFeedback", e);
        }

        private void sftTree1_HeaderClicked(object sender, Softelvdm.SftTreeNET.HeaderClickedEventArgs e) {
            DumpValues("HeaderClicked", e);
        }

        private void sftTree1_HeaderDoubleClicked(object sender, Softelvdm.SftTreeNET.HeaderClickedEventArgs e) {
            DumpValues("HeaderDoubleClicked", e);
        }

        private void sftTree1_HeaderHeightChanged(object sender, EventArgs e) {
            DumpValues("HeaderHeightChanged", e);
        }

        private void sftTree1_HorizontalOffsetChanged(object sender, Softelvdm.SftTreeNET.HorizontalOffsetChangedEventArgs e) {
            DumpValues("HorizontalOffsetChanged", e);
        }

        private void sftTree1_ItemClick(object sender, Softelvdm.SftTreeNET.ItemClickEventArgs e) {
            DumpValues("ItemClick", e);

            if (e.Item != null && e.Cell != null && e.Item.UsageLocation == UsageLocationEnum.items && e.Cell.ColumnIndex == 2)
                e.Cell.Edit();  // Start cell editing

        }

        private void sftTree1_ItemCollapsed(object sender, Softelvdm.SftTreeNET.ItemCollapsedEventArgs e) {
            DumpValues("ItemCollapsed", e);
        }

        private void sftTree1_ItemDoubleClick(object sender, Softelvdm.SftTreeNET.ItemClickEventArgs e) {
            DumpValues("ItemDoubleClick", e);
        }

        private void sftTree1_ItemExpanded(object sender, Softelvdm.SftTreeNET.ItemExpandedEventArgs e) {
            DumpValues("ItemExpanded", e);
        }

        private void sftTree1_ItemRemoved(object sender, Softelvdm.SftTreeNET.ItemRemovedEventArgs e) {
            DumpValues("ItemRemoved", e);
        }

        private void sftTree1_KeyDown(object sender, KeyEventArgs e) {
            DumpValues("KeyDown", e);
        }

        private void sftTree1_KeyPress(object sender, KeyPressEventArgs e) {
            DumpValues("KeyPress", e);
        }

        private void sftTree1_KeyUp(object sender, KeyEventArgs e) {
            DumpValues("KeyUp", e);
        }

        private void sftTree1_Leave(object sender, EventArgs e) {
            DumpValues("Leave", e);
        }

        private void sftTree1_MouseClick(object sender, MouseEventArgs e) {
            DumpValues("MouseClick", e);
        }

        private void sftTree1_MouseDoubleClick(object sender, MouseEventArgs e) {
            DumpValues("MouseDoubleClick", e);
        }

        private void sftTree1_MouseDown(object sender, MouseEventArgs e) {
            DumpValues("MouseDown", e);
        }

        private void sftTree1_MouseEnter(object sender, EventArgs e) {
            DumpValues("MouseEnter", e);
        }

        private void sftTree1_MouseHover(object sender, EventArgs e) {
            DumpValues("MouseHover", e);
        }

        private void sftTree1_MouseLeave(object sender, EventArgs e) {
            DumpValues("MouseLeave", e);
        }

        private void sftTree1_MouseMove(object sender, MouseEventArgs e) {
            // DumpValues("MouseMove", e);  // deliberately suppressed
        }

        private void sftTree1_MouseMoveHoverTimer(object sender, EventArgs e) {
            DumpValues("MouseMoveHoverTimer", e);
        }

        private void sftTree1_MouseMoveTimer(object sender, EventArgs e) {
            DumpValues("MouseMoveTimer", e);
        }

        private void sftTree1_MouseUp(object sender, MouseEventArgs e) {
            DumpValues("MouseUp", e);
        }

        private void sftTree1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
            DumpValues("PreviewKeyDown", e);
        }

        private void sftTree1_QueryContinueDrag(object sender, QueryContinueDragEventArgs e) {
            DumpValues("QueryContinueDrag", e);
        }

        private void sftTree1_RadioButtonClicked(object sender, Softelvdm.SftTreeNET.PartEventArgs e) {
            DumpValues("RadioButtonClicked", e);
        }

        private void sftTree1_SelectionChanged(object sender, EventArgs e) {
            DumpValues("SelectionChanged", e);
        }

        private void sftTree1_ShowScrollTip(object sender, Softelvdm.SftTreeNET.ToolTipEventArgs e) {
            DumpValues("ShowScrollTip", e);
        }

        private void sftTree1_ShowToolTip(object sender, Softelvdm.SftTreeNET.ToolTipEventArgs e) {
            DumpValues("ShowToolTip", e);

            if (e.Usage == UsageLocationEnum.items && e.Cell != null && e.Cell.OwningItem.VisibleIndex == 2 && e.Cell.ColumnIndex == 3) {
                e.ToolTipIcon = ToolTipIcon.Info;
                e.ToolTipTitle = "Balloon Tooltip";
                e.ToolTipStyle = Softelvdm.Controls.ToolTipAppearanceEnum.Balloon;
                e.ToolTipText = "A simple explanatory tooltip\nfor just this cell";
            }
        }

        private void sftTree1_SplitterOffsetChanged(object sender, EventArgs e) {
            DumpValues("SplitterOffsetChanged", e);
        }

        private void sftTree1_TopItemChanged(object sender, EventArgs e) {
            DumpValues("TopItemChanged", e);
        }

        // Handle all the cell navigation for the text box here 
        private void textBox1_KeyDown(object sender, KeyEventArgs e) {
            if (e.KeyCode == Keys.Up) {
                sftTree1.EditNavigate(EditNavigateEnum.Up);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Down) {
                sftTree1.EditNavigate(EditNavigateEnum.Down);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Left && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Left
                sftTree1.EditNavigate(EditNavigateEnum.Left);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Right && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Right
                sftTree1.EditNavigate(EditNavigateEnum.Right);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Home && (e.Modifiers & Keys.Control) != 0) { // Ctrl+Home
                sftTree1.EditNavigate(EditNavigateEnum.Home);
                e.Handled = true;
            } else if (e.KeyCode == Keys.End && (e.Modifiers & Keys.Control) != 0) { // Ctrl+End
                sftTree1.EditNavigate(EditNavigateEnum.End);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Tab && (e.Modifiers & Keys.Shift) != 0) { // Shift+Tab
                sftTree1.EditNavigate(EditNavigateEnum.Left);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Tab && (e.Modifiers & Keys.Shift) == 0) { // Tab
                sftTree1.EditNavigate(EditNavigateEnum.Right);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Escape) { // ESC
                sftTree1.EndEdit(false);
                e.Handled = true;
            } else if (e.KeyCode == Keys.Return) { // Return
                sftTree1.EndEdit(true);
                e.Handled = true;
            }
        }

        // Textboxes normally don't want Tab and Escape keys, so we enable these here
        private void textBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
            if (e.KeyCode == Keys.Tab)
                e.IsInputKey = true;
            else if (e.KeyCode == Keys.Escape)
                e.IsInputKey = true;
        }
    }
}